package model

import (
	"ginblog/utils/errmsg"
	"gorm.io/gorm"
)

type Article struct {
	Category Category `gorm:"foreignkey:Cid"`
	gorm.Model
	Title        string `gorm:"type:varchar(100);not null" json:"title"`
	Cid          int    `gorm:"type:int;not null" json:"cid"`
	Desc         string `gorm:"type:varchar(200)" json:"desc"`
	Content      string `gorm:"type:longtext" json:"content"`
	Img          string `gorm:"type:varchar(100)" json:"img"`
	CommentCount int    `gorm:"type:int;not null;default:0" json:"comment_count"`
	ReadCount    int    `gorm:"type:int;not null;default:0" json:"read_count"`
}

// CreateArt 新增文章
// CreateArt 创建一篇新文章
// 参数:
//
//	data *Article: 指向Article类型的指针，包含文章的详细信息
//
// 返回值:
//
//	int: 返回错误代码，表示创建操作的状态
func CreateArt(data *Article) int {
	// 使用db对象创建新文章记录
	err := db.Create(&data).Error
	// 如果创建过程中出现错误
	if err != nil {
		// 返回错误代码，表示创建失败
		return errmsg.ERROR
	}
	// 如果创建成功，返回成功代码
	return errmsg.SUCCESS
}

// GetCateArt 查询分类下的所有文章
// GetCateArt 根据分类ID获取该分类下的文章列表及总数。
// 参数:
//
//	id - 分类ID。
//	pageSize - 每页显示的文章数量。
//	pageNum - 当前页码。
//
// 返回值:
//
//	[]Article - 文章列表。
//	int - 错误代码，表示操作是否成功。
//	int64 - 该分类下的文章总数。
func GetCateArt(id int, pageSize int, pageNum int) ([]Article, int, int64) {
	var cateArtList []Article
	var total int64

	// 预加载分类信息并查询文章列表
	err = db.Preload("Category").Limit(pageSize).Offset((pageNum-1)*pageSize).Where(
		"cid =?", id).Find(&cateArtList).Error
	// 查询该分类下的文章总数
	db.Model(&cateArtList).Where("cid =?", id).Count(&total)
	// 检查查询错误
	if err != nil {
		return nil, errmsg.ERROR_CATE_NOT_EXIST, 0
	}
	// 返回文章列表、成功代码和文章总数
	return cateArtList, errmsg.SUCCESS, total
}

// GetArtInfo 查询单个文章
// GetArtInfo 根据文章ID获取文章信息并增加阅读计数。
// 参数:
//
//	id - 文章的唯一标识符。
//
// 返回值:
//
//	Article - 文章结构体，包含文章详细信息。
//	int - 错误代码，表示文章是否成功获取。
func GetArtInfo(id int) (Article, int) {
	var art Article
	// 查询指定ID的文章，并预加载分类信息。
	err = db.Where("id = ?", id).Preload("Category").First(&art).Error
	// 更新文章的阅读计数。
	db.Model(&art).Where("id = ?", id).UpdateColumn("read_count", gorm.Expr("read_count + ?", 1))
	// 检查查询过程中是否有错误发生。
	if err != nil {
		return art, errmsg.ERROR_ART_NOT_EXIST
	}
	// 如果没有错误，返回成功代码和文章信息。
	return art, errmsg.SUCCESS
}

// GetArt 查询文章列表
// GetArt 获取文章列表及总数
// 参数:
//
//	pageSize - 每页显示的文章数量
//	pageNum - 当前页码
//
// 返回值:
//
//	[]Article - 文章列表
//	int - 错误代码，表示请求是否成功
//	int64 - 文章总数
func GetArt(pageSize int, pageNum int) ([]Article, int, int64) {
	// 初始化文章列表
	var articleList []Article
	// 初始化错误变量
	var err error
	// 初始化文章总数变量
	var total int64

	// 查询文章列表，包括分页和排序
	err = db.Select("article.id, title, img, created_at, updated_at, `desc`, comment_count, read_count, category.name").
		Limit(pageSize).
		Offset((pageNum - 1) * pageSize).
		Order("Created_At DESC").
		Joins("Category").
		Find(&articleList).Error
	// 单独计数
	db.Model(&articleList).Count(&total)
	// 检查查询过程中是否有错误发生
	if err != nil {
		// 如果有错误，返回空文章列表，错误代码，和零总数
		return nil, errmsg.ERROR, 0
	}
	// 如果查询成功，返回文章列表，成功代码，和文章总数
	return articleList, errmsg.SUCCESS, total

}

// SearchArticle 搜索文章标题
// SearchArticle 根据标题搜索文章。
// 该函数接收标题、页面大小和页码作为参数，返回文章列表、状态码和总记录数。
// 参数:
//
//	title - 文章标题，用于模糊搜索。
//	pageSize - 每页显示的文章数量。
//	pageNum - 当前页码。
//
// 返回值:
//
//	[]Article - 文章列表。
//	int - 状态码，表示操作结果的成功或失败。
//	int64 - 搜索结果的总记录数。
func SearchArticle(title string, pageSize int, pageNum int) ([]Article, int, int64) {
	// 初始化文章列表、错误变量和总记录数变量。
	var articleList []Article
	var err error
	var total int64

	// 执行数据库查询，根据标题模糊搜索文章，按创建时间降序排序，分页获取结果。
	err = db.Select("article.id,title, img, created_at, updated_at, `desc`, comment_count, read_count, Category.name").Order("Created_At DESC").Joins("Category").Where("title LIKE ?",
		title+"%",
	).Limit(pageSize).Offset((pageNum - 1) * pageSize).Find(&articleList).Error

	// 单独计数，计算符合搜索条件的总记录数。
	db.Model(&articleList).Where("title LIKE ?",
		title+"%",
	).Count(&total)

	// 如果查询过程中发生错误，返回错误信息和0作为总记录数。
	if err != nil {
		return nil, errmsg.ERROR, 0
	}
	// 返回文章列表、成功状态码和总记录数。
	return articleList, errmsg.SUCCESS, total
}

// EditArt 编辑文章
// EditArt 编辑文章信息。
// 参数:
//
//	id - 文章的ID，用于数据库中定位要编辑的文章。
//	data - 指向一个Article结构体的指针，包含要更新的文章信息。
//
// 返回值:
//
//	int - 返回错误代码，表示执行编辑操作的结果。
func EditArt(id int, data *Article) int {
	// 初始化一个空的文章结构体，用于接收要更新的数据。
	var art Article
	// 创建一个空的map，用于存储文章的更新信息。
	var maps = make(map[string]interface{})
	// 将文章的标题、分类ID、描述、内容和图片路径存入map中。
	maps["title"] = data.Title
	maps["cid"] = data.Cid
	maps["desc"] = data.Desc
	maps["content"] = data.Content
	maps["img"] = data.Img

	// 使用db对象的Model方法指定操作的文章表，Where方法指定更新条件，Updates方法应用更新数据。
	// 如果发生错误，返回错误代码。
	err = db.Model(&art).Where("id = ? ", id).Updates(&maps).Error
	if err != nil {
		return errmsg.ERROR
	}
	// 如果更新成功，返回成功代码。
	return errmsg.SUCCESS
}

// DeleteArt 删除文章
// DeleteArt deletes an article by its ID.
// Parameter id: The unique identifier of the article to be deleted.
// Return value: Returns the deletion status code. If the deletion fails, returns errmsg.ERROR; if successful, returns errmsg.SUCCESS.
func DeleteArt(id int) int {
	// Initialize an Article type variable to store article information.
	var art Article
	// Use the article ID to query and delete the article record in the database.
	err = db.Where("id = ? ", id).Delete(&art).Error
	// If the deletion operation encounters an error, return the error code.
	if err != nil {
		return errmsg.ERROR
	}
	// If the deletion is successful, return the success code.
	return errmsg.SUCCESS
}
